#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import sys

from common.common import exter_attack
from common.common import output_result_file
from common.const import SysData
from common.parse_parafile import ParamFileUtil, add_env_param
from common.schemas.thrift_base_data_type import Application, SubJob
from common.schemas.thrift_plugin import BackupJob, RestoreJob
from saporacle.comm.common_util import logger_watched
from saporacle.comm.logger import logger
from saporacle.factory import Factory


class SAPOracleApi:

    """资源"""

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def check_application(param: dict, pid: str) -> dict:
        application = Application(**param["application"])
        factory = Factory(pid)
        service = factory.create_resource_service(application)
        result = service.check_application(application)
        return result.dict(by_alias=True)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def query_cluster(param: dict, pid: str) -> dict:
        application = Application(**param["application"])
        factory = Factory(pid)
        service = factory.create_resource_service(application)
        resource = service.query_cluster(application)
        return resource.dict(by_alias=True)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def query_job_permission(param: dict, pid: str) -> dict:
        application = Application(**param["application"])
        factory = Factory(pid)
        service = factory.create_resource_service(application)
        permission = service.query_job_permission(application)
        return permission.dict(by_alias=True)

    """备份"""

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def check_backup_job_type(param: dict, pid: str) -> dict:
        backup_job = BackupJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        result = service.check_backup_job_type(backup_job)
        return result.dict(by_alias=True)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def allow_backup_in_local_node(param: dict, pid: str) -> dict:
        backup_job = BackupJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        result = service.allow_backup_in_local_node(backup_job)
        return result.dict(by_alias=True)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def backup_prerequisite(param: dict, pid: str) -> None:
        backup_job = BackupJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        service.backup_prerequisite(backup_job)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def backup_gen_sub_job(param: dict, pid: str) -> list[dict]:
        backup_job = BackupJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        sub_jobs = service.backup_gen_sub_job(backup_job)
        return [sub_job.dict(by_alias=True) for sub_job in sub_jobs]

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def backup(param: dict, pid: str) -> None:
        backup_job = BackupJob(**param["job"])
        sub_job = SubJob(**param["subJob"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        service.backup(backup_job, sub_job)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def backup_post_job(param: dict, pid: str) -> None:
        job_result = param["backupJobResult"]
        backup_job = BackupJob(**param["job"])
        sub_job = SubJob(**param["subJob"])
        factory = Factory(pid)
        service = factory.create_backup_service(backup_job)
        service.backup_post_job(job_result, backup_job, sub_job)

    """中止"""

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def abort_job(param: dict, pid: str) -> dict:
        return SAPOracleApi.pause_job(param, pid)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def pause_job(param: dict, pid: str) -> dict:
        if param["job"].get("protectObject"):
            job = BackupJob(**param["job"])
            factory = Factory(pid)
            service = factory.create_backup_service(job)
        elif param["job"].get("targetObject"):
            job = RestoreJob(**param["job"])
            factory = Factory(pid)
            service = factory.create_restore_service(job)
        sub_job = SubJob(**param["subJob"])
        result = service.pause_job(job, sub_job)
        return result.dict(by_alias=True)

    """恢复"""

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def allow_restore_in_local_node(param: dict, pid: str) -> dict:
        restore_job = RestoreJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_restore_service(restore_job)
        result = service.allow_restore_in_local_node(restore_job)
        return result.dict(by_alias=True)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def restore_prerequisite(param: dict, pid: str) -> None:
        restore_job = RestoreJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_restore_service(restore_job)
        service.restore_prerequisite(restore_job)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def restore_gen_sub_job(param: dict, pid: str) -> list[dict]:
        restore_job = RestoreJob(**param["job"])
        factory = Factory(pid)
        service = factory.create_restore_service(restore_job)
        sub_jobs = service.restore_gen_sub_job(restore_job)
        return [sub_job.dict(by_alias=True) for sub_job in sub_jobs]

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def restore(param: dict, pid: str) -> None:
        restore_job = RestoreJob(**param["job"])
        sub_job = SubJob(**param["subJob"])
        factory = Factory(pid)
        service = factory.create_restore_service(restore_job)
        service.restore(restore_job, sub_job)

    @staticmethod
    @exter_attack
    @logger_watched(1)
    def restore_post_job(param: dict, pid: str) -> None:
        job_result = param["restoreJobResult"]
        restore_job = RestoreJob(**param["job"])
        sub_job = SubJob(**param["subJob"])
        factory = Factory(pid)
        service = factory.create_restore_service(restore_job)
        service.restore_post_job(job_result, restore_job, sub_job)


if __name__ == "__main__":
    """
     功能描述：主任务执行
     参数：
     @xxx.py：argv[0] api.py python文件
     @fun_type：argv[1] 方法类型
     @pid：argv[2] 请求ID
     @job_id：argv[3] 主任务任务ID
     @sub_job_id: argv[4] 子任务ID
     例：python3 api.py fun_type pid job_id sub_job_id
    """
    SysData.SYS_STDIN = sys.stdin.readline()
    args = sys.argv + [""] * 4
    [add_env_param(k, v) for k, v in zip(["pid", "job_id", "sub_job_id"], args[2:5])]
    try:
        _param: dict = ParamFileUtil.parse_param_windows_file(args[2])
        response = getattr(SAPOracleApi, args[1])(_param, args[2])
        response is not None and output_result_file(args[2], response)
    except Exception as e:
        logger.error(f"Unknown exception!!! %s", e, exc_info=1)
        raise e
